{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 零基础实战机器学习\n",
    "\n",
    "## 第16讲 会员流失情况评估\n",
    "\n",
    "作者 黄佳\n",
    "\n",
    "极客时间专栏链接：https://time.geekbang.org/column/intro/438\n",
    "\n",
    "\n",
    "问题：判断易速鲜花会员的是否会流失情况\n",
    "\n",
    "易速鲜花公司拥有多年的会员记录，以及会员停止续费的情况。\n",
    "\n",
    "通过逻辑回归和神经网络等机器学习模型，我们可以判断出客户是否离开，这是一个典型的的二元分类问题。\n",
    "\n",
    "这一讲我们集中介绍分类问题的评估指标：混淆矩阵，精确率，召回率，F1分数，ROC曲线和AUC。\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 数据的读入和预处理"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 导入数据包\n",
    "import numpy as np # \n",
    "import pandas as pd #\n",
    "import matplotlib.pyplot as plt #"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>用户码</th>\n",
       "      <th>性别</th>\n",
       "      <th>玫瑰套餐</th>\n",
       "      <th>紫罗兰套餐</th>\n",
       "      <th>郁金香套餐</th>\n",
       "      <th>百合套餐</th>\n",
       "      <th>康乃馨套餐</th>\n",
       "      <th>胡姬花套餐</th>\n",
       "      <th>生日套餐</th>\n",
       "      <th>情人节套餐</th>\n",
       "      <th>会员卡类型</th>\n",
       "      <th>入会月数</th>\n",
       "      <th>会费支付方式</th>\n",
       "      <th>平均月消费</th>\n",
       "      <th>总消费</th>\n",
       "      <th>已停付会费</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>女</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>年卡</td>\n",
       "      <td>9</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>65.60</td>\n",
       "      <td>593.3</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>男</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>月卡</td>\n",
       "      <td>9</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>59.90</td>\n",
       "      <td>542.4</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>男</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>月卡</td>\n",
       "      <td>4</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>73.90</td>\n",
       "      <td>280.85</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>男</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>月卡</td>\n",
       "      <td>13</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>98.00</td>\n",
       "      <td>1237.85</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>女</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>月卡</td>\n",
       "      <td>9</td>\n",
       "      <td>花呗付款</td>\n",
       "      <td>69.40</td>\n",
       "      <td>571.45</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7038</th>\n",
       "      <td>7039</td>\n",
       "      <td>女</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>年卡</td>\n",
       "      <td>13</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>55.15</td>\n",
       "      <td>742.9</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7039</th>\n",
       "      <td>7040</td>\n",
       "      <td>男</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>月卡</td>\n",
       "      <td>2</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>50.30</td>\n",
       "      <td>92.75</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7040</th>\n",
       "      <td>7041</td>\n",
       "      <td>男</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>月卡</td>\n",
       "      <td>22</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>85.10</td>\n",
       "      <td>1873.7</td>\n",
       "      <td>是</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7041</th>\n",
       "      <td>7042</td>\n",
       "      <td>男</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>双年卡</td>\n",
       "      <td>67</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>67.85</td>\n",
       "      <td>4627.65</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7042</th>\n",
       "      <td>7043</td>\n",
       "      <td>男</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>否</td>\n",
       "      <td>是</td>\n",
       "      <td>是</td>\n",
       "      <td>双年卡</td>\n",
       "      <td>63</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>59.00</td>\n",
       "      <td>3707.6</td>\n",
       "      <td>否</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>7043 rows × 16 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       用户码 性别 玫瑰套餐 紫罗兰套餐 郁金香套餐 百合套餐 康乃馨套餐 胡姬花套餐 生日套餐 情人节套餐 会员卡类型  入会月数 会费支付方式  \\\n",
       "0        1  女    是     是     否    是     否     是    是     否    年卡     9   手工转账   \n",
       "1        2  男    否     否     否    否     否     否    否     是    月卡     9   手工转账   \n",
       "2        3  男    否     否     否    否     是     否    否     否    月卡     4  就餐时付费   \n",
       "3        4  男    是     否     否    是     是     否    是     是    月卡    13  就餐时付费   \n",
       "4        5  女    否     是     否    否     否     是    是     是    月卡     9   花呗付款   \n",
       "...    ... ..  ...   ...   ...  ...   ...   ...  ...   ...   ...   ...    ...   \n",
       "7038  7039  女    否     否     是    否     否     是    否     否    年卡    13   手工转账   \n",
       "7039  7040  男    否     否     否    是     否     否    否     否    月卡     2   手工转账   \n",
       "7040  7041  男    是     否     否    否     否     否    否     是    月卡    22  就餐时付费   \n",
       "7041  7042  男    是     是     是    否     是     是    否     是   双年卡    67   手工转账   \n",
       "7042  7043  男    是     是     是    是     是     否    是     是   双年卡    63  就餐时付费   \n",
       "\n",
       "      平均月消费      总消费 已停付会费  \n",
       "0     65.60    593.3     否  \n",
       "1     59.90    542.4     否  \n",
       "2     73.90   280.85     是  \n",
       "3     98.00  1237.85     是  \n",
       "4     69.40   571.45     否  \n",
       "...     ...      ...   ...  \n",
       "7038  55.15    742.9     否  \n",
       "7039  50.30    92.75     否  \n",
       "7040  85.10   1873.7     是  \n",
       "7041  67.85  4627.65     否  \n",
       "7042  59.00   3707.6     否  \n",
       "\n",
       "[7043 rows x 16 columns]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_member = pd.read_csv('易速鲜花会员留存.csv')\n",
    "df_member"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据清洗"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "#把总消费字段转换成数值字段\n",
    "df_member['总消费'] = pd.to_numeric(df_member['总消费'], errors='coerce')\n",
    "df_member['总消费'].fillna(0, inplace=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.figure(figsize=(6,4))\n",
    "ax = df_member.groupby('已停付会费').count()['用户码'].plot.pie(autopct='%1.0f%%') #饼图\n",
    "plt.xlabel('是否流失')\n",
    "plt.show() #显示"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 特征工程"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_member['已停付会费'].replace(to_replace='是', value=1, inplace=True) #流失-1\n",
    "df_member['已停付会费'].replace(to_replace='否',  value=0, inplace=True) #未流失-0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "df_member['性别'].replace(to_replace='女', value=0, inplace=True) #女生-0\n",
    "df_member['性别'].replace(to_replace='男', value=1, inplace=True) #男生-1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# 字段中'Yes' or 'No'转换成为模型可以读取的数值,（布尔型数据，也是数值数据）\n",
    "binary_features = ['玫瑰套餐', '紫罗兰套餐', '郁金香套餐', '百合套餐', '康乃馨套餐', '胡姬花套餐', \n",
    "                   '生日套餐','情人节套餐']\n",
    "for field in binary_features:\n",
    "    df_member[field] = df_member[field] == '是'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>用户码</th>\n",
       "      <th>性别</th>\n",
       "      <th>玫瑰套餐</th>\n",
       "      <th>紫罗兰套餐</th>\n",
       "      <th>郁金香套餐</th>\n",
       "      <th>百合套餐</th>\n",
       "      <th>康乃馨套餐</th>\n",
       "      <th>胡姬花套餐</th>\n",
       "      <th>生日套餐</th>\n",
       "      <th>情人节套餐</th>\n",
       "      <th>会员卡类型</th>\n",
       "      <th>入会月数</th>\n",
       "      <th>会费支付方式</th>\n",
       "      <th>平均月消费</th>\n",
       "      <th>总消费</th>\n",
       "      <th>已停付会费</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>年卡</td>\n",
       "      <td>9</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>65.60</td>\n",
       "      <td>593.30</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>月卡</td>\n",
       "      <td>9</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>59.90</td>\n",
       "      <td>542.40</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>月卡</td>\n",
       "      <td>4</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>73.90</td>\n",
       "      <td>280.85</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>月卡</td>\n",
       "      <td>13</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>98.00</td>\n",
       "      <td>1237.85</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>月卡</td>\n",
       "      <td>9</td>\n",
       "      <td>花呗付款</td>\n",
       "      <td>69.40</td>\n",
       "      <td>571.45</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7038</th>\n",
       "      <td>7039</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>年卡</td>\n",
       "      <td>13</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>55.15</td>\n",
       "      <td>742.90</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7039</th>\n",
       "      <td>7040</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>月卡</td>\n",
       "      <td>2</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>50.30</td>\n",
       "      <td>92.75</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7040</th>\n",
       "      <td>7041</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>月卡</td>\n",
       "      <td>22</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>85.10</td>\n",
       "      <td>1873.70</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7041</th>\n",
       "      <td>7042</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>双年卡</td>\n",
       "      <td>67</td>\n",
       "      <td>手工转账</td>\n",
       "      <td>67.85</td>\n",
       "      <td>4627.65</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7042</th>\n",
       "      <td>7043</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>双年卡</td>\n",
       "      <td>63</td>\n",
       "      <td>就餐时付费</td>\n",
       "      <td>59.00</td>\n",
       "      <td>3707.60</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>7043 rows × 16 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       用户码  性别   玫瑰套餐  紫罗兰套餐  郁金香套餐   百合套餐  康乃馨套餐  胡姬花套餐   生日套餐  情人节套餐 会员卡类型  \\\n",
       "0        1   0   True   True  False   True  False   True   True  False    年卡   \n",
       "1        2   1  False  False  False  False  False  False  False   True    月卡   \n",
       "2        3   1  False  False  False  False   True  False  False  False    月卡   \n",
       "3        4   1   True  False  False   True   True  False   True   True    月卡   \n",
       "4        5   0  False   True  False  False  False   True   True   True    月卡   \n",
       "...    ...  ..    ...    ...    ...    ...    ...    ...    ...    ...   ...   \n",
       "7038  7039   0  False  False   True  False  False   True  False  False    年卡   \n",
       "7039  7040   1  False  False  False   True  False  False  False  False    月卡   \n",
       "7040  7041   1   True  False  False  False  False  False  False   True    月卡   \n",
       "7041  7042   1   True   True   True  False   True   True  False   True   双年卡   \n",
       "7042  7043   1   True   True   True   True   True  False   True   True   双年卡   \n",
       "\n",
       "      入会月数 会费支付方式  平均月消费      总消费  已停付会费  \n",
       "0        9   手工转账  65.60   593.30      0  \n",
       "1        9   手工转账  59.90   542.40      0  \n",
       "2        4  就餐时付费  73.90   280.85      1  \n",
       "3       13  就餐时付费  98.00  1237.85      1  \n",
       "4        9   花呗付款  69.40   571.45      0  \n",
       "...    ...    ...    ...      ...    ...  \n",
       "7038    13   手工转账  55.15   742.90      0  \n",
       "7039     2   手工转账  50.30    92.75      0  \n",
       "7040    22  就餐时付费  85.10  1873.70      1  \n",
       "7041    67   手工转账  67.85  4627.65      0  \n",
       "7042    63  就餐时付费  59.00  3707.60      0  \n",
       "\n",
       "[7043 rows x 16 columns]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df_member"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 数据整理\n",
    "先做数据整理工作，把每个数据字段都转换为可以处理的字段"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>用户码</th>\n",
       "      <th>性别</th>\n",
       "      <th>玫瑰套餐</th>\n",
       "      <th>紫罗兰套餐</th>\n",
       "      <th>郁金香套餐</th>\n",
       "      <th>百合套餐</th>\n",
       "      <th>康乃馨套餐</th>\n",
       "      <th>胡姬花套餐</th>\n",
       "      <th>生日套餐</th>\n",
       "      <th>情人节套餐</th>\n",
       "      <th>入会月数</th>\n",
       "      <th>平均月消费</th>\n",
       "      <th>总消费</th>\n",
       "      <th>已停付会费</th>\n",
       "      <th>会员卡类型_年卡</th>\n",
       "      <th>会员卡类型_月卡</th>\n",
       "      <th>会费支付方式_微信自动扣款</th>\n",
       "      <th>会费支付方式_手工转账</th>\n",
       "      <th>会费支付方式_花呗付款</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>9</td>\n",
       "      <td>65.60</td>\n",
       "      <td>593.30</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>9</td>\n",
       "      <td>59.90</td>\n",
       "      <td>542.40</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>3</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>4</td>\n",
       "      <td>73.90</td>\n",
       "      <td>280.85</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>4</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>13</td>\n",
       "      <td>98.00</td>\n",
       "      <td>1237.85</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>5</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>9</td>\n",
       "      <td>69.40</td>\n",
       "      <td>571.45</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7038</th>\n",
       "      <td>7039</td>\n",
       "      <td>0</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>13</td>\n",
       "      <td>55.15</td>\n",
       "      <td>742.90</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7039</th>\n",
       "      <td>7040</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>2</td>\n",
       "      <td>50.30</td>\n",
       "      <td>92.75</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7040</th>\n",
       "      <td>7041</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>22</td>\n",
       "      <td>85.10</td>\n",
       "      <td>1873.70</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7041</th>\n",
       "      <td>7042</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>67</td>\n",
       "      <td>67.85</td>\n",
       "      <td>4627.65</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7042</th>\n",
       "      <td>7043</td>\n",
       "      <td>1</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>False</td>\n",
       "      <td>True</td>\n",
       "      <td>True</td>\n",
       "      <td>63</td>\n",
       "      <td>59.00</td>\n",
       "      <td>3707.60</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>7043 rows × 19 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "       用户码  性别   玫瑰套餐  紫罗兰套餐  郁金香套餐   百合套餐  康乃馨套餐  胡姬花套餐   生日套餐  情人节套餐  入会月数  \\\n",
       "0        1   0   True   True  False   True  False   True   True  False     9   \n",
       "1        2   1  False  False  False  False  False  False  False   True     9   \n",
       "2        3   1  False  False  False  False   True  False  False  False     4   \n",
       "3        4   1   True  False  False   True   True  False   True   True    13   \n",
       "4        5   0  False   True  False  False  False   True   True   True     9   \n",
       "...    ...  ..    ...    ...    ...    ...    ...    ...    ...    ...   ...   \n",
       "7038  7039   0  False  False   True  False  False   True  False  False    13   \n",
       "7039  7040   1  False  False  False   True  False  False  False  False     2   \n",
       "7040  7041   1   True  False  False  False  False  False  False   True    22   \n",
       "7041  7042   1   True   True   True  False   True   True  False   True    67   \n",
       "7042  7043   1   True   True   True   True   True  False   True   True    63   \n",
       "\n",
       "      平均月消费      总消费  已停付会费  会员卡类型_年卡  会员卡类型_月卡  会费支付方式_微信自动扣款  会费支付方式_手工转账  \\\n",
       "0     65.60   593.30      0         1         0              0            1   \n",
       "1     59.90   542.40      0         0         1              0            1   \n",
       "2     73.90   280.85      1         0         1              0            0   \n",
       "3     98.00  1237.85      1         0         1              0            0   \n",
       "4     69.40   571.45      0         0         1              0            0   \n",
       "...     ...      ...    ...       ...       ...            ...          ...   \n",
       "7038  55.15   742.90      0         1         0              0            1   \n",
       "7039  50.30    92.75      0         0         1              0            1   \n",
       "7040  85.10  1873.70      1         0         1              0            0   \n",
       "7041  67.85  4627.65      0         0         0              0            1   \n",
       "7042  59.00  3707.60      0         0         0              0            0   \n",
       "\n",
       "      会费支付方式_花呗付款  \n",
       "0               0  \n",
       "1               0  \n",
       "2               0  \n",
       "3               0  \n",
       "4               1  \n",
       "...           ...  \n",
       "7038            0  \n",
       "7039            0  \n",
       "7040            0  \n",
       "7041            0  \n",
       "7042            0  \n",
       "\n",
       "[7043 rows x 19 columns]"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# One hot encode 分类字段\n",
    "category_features = ['会员卡类型', '会费支付方式']\n",
    "df_member = pd.get_dummies(df_member, drop_first=True, columns=category_features)\n",
    "df_member"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建特征集和标签集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = df_member.drop(['用户码','已停付会费'], axis = 1) # 构建特征集，用户吗字段属于无用特征\n",
    "y = df_member.已停付会费.values # 构建标签集"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 拆分数据集"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "X_train, X_test, y_train, y_test = train_test_split(X,y,test_size = 0.2, random_state = 4)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 选择算法\n",
    "\n",
    "这里我们比较逻辑回归和神经网络两种算法"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 逻辑回归模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 导入模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression #导入逻辑回归模型\n",
    "logreg = LogisticRegression() # logreg,就代表是逻辑回归模型"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 训练机器"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "C:\\Users\\jacky.huang\\Anaconda3\\lib\\site-packages\\sklearn\\linear_model\\_logistic.py:762: ConvergenceWarning: lbfgs failed to converge (status=1):\n",
      "STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.\n",
      "\n",
      "Increase the number of iterations (max_iter) or scale the data as shown in:\n",
      "    https://scikit-learn.org/stable/modules/preprocessing.html\n",
      "Please also refer to the documentation for alternative solver options:\n",
      "    https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression\n",
      "  n_iter_i = _check_optimize_result(\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "LogisticRegression()"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "logreg.fit(X_train,y_train) # fit,就相当于是梯度下降"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 评估分数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "SK-learn逻辑回归预测准确率78.42%\n"
     ]
    }
   ],
   "source": [
    "print(\"SK-learn逻辑回归预测准确率{:.2f}%\".format(logreg.score(X_test,y_test)*100))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 预测结果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "逻辑回归对测试集第一个用户的预测结果 0\n"
     ]
    }
   ],
   "source": [
    "y_pred_logreg = logreg.predict(X_test)\n",
    "print(\"逻辑回归对测试集第一个用户的预测结果\", y_pred_logreg[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 混淆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import confusion_matrix # 导入混淆矩阵\n",
    "import seaborn as sns #导入seaborn画图工具箱\n",
    "def show_matrix(y_test, y_pred, label): # 定义一个函数显示混淆矩阵\n",
    "    cm = confusion_matrix(y_test,y_pred) # 调用混淆矩阵\n",
    "    plt.title(label) # 标题\n",
    "    sns.heatmap(cm,annot=True,cmap=\"Blues\",fmt=\"d\",cbar=False) # 热力图设定\n",
    "    plt.show() # 显示混淆矩阵"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_matrix(y_test, y_pred_logreg,label='混淆矩阵（逻辑回归)') # 逻辑回归"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 分类报告"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import classification_report # 导入分类报告\n",
    "def show_report(X_test, y_test, y_pred): # 定义一个函数显示分类报告\n",
    "    # print (y_pred)\n",
    "    #np.set_printoptions(threshold=np.inf)\n",
    "    # print (np.where(predictions > 0.5, 0, predictions))\n",
    "#     if y_test.shape != (2000,1):\n",
    "#         y_test = y_test.values # 把Panda series转换成Numpy array\n",
    "#         y_test = y_test.reshape((len(y_test),1)) # 转换成与y_pred相同的形状 \n",
    "    #target_names = [str(x) for x in lb.classes_]\n",
    "    print(classification_report(y_test,y_pred,labels=[0, 1])) #打印分类报告  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.83      0.89      0.86      1048\n",
      "           1       0.60      0.47      0.53       361\n",
      "\n",
      "    accuracy                           0.78      1409\n",
      "   macro avg       0.72      0.68      0.69      1409\n",
      "weighted avg       0.77      0.78      0.78      1409\n",
      "\n"
     ]
    }
   ],
   "source": [
    "show_report(X_test, y_test, y_pred_logreg)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 神经网络模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "#!pip install keras\n",
    "#!pip install tensorflow"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense (Dense)                (None, 12)                216       \n",
      "_________________________________________________________________\n",
      "dense_1 (Dense)              (None, 24)                312       \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 1)                 25        \n",
      "=================================================================\n",
      "Total params: 553\n",
      "Trainable params: 553\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "import keras # 导入Keras库\n",
    "from keras.models import Sequential # 导入Keras序贯模型\n",
    "from keras.layers import Dense # 导入Keras密集连接层\n",
    "dnn = Sequential() # 创建一个序贯DNN模型\n",
    "dnn.add(Dense(units=12, input_dim=17, activation = 'relu')) # 添加输入层\n",
    "dnn.add(Dense(units=24, activation = 'relu')) # 添加隐层\n",
    "dnn.add(Dense(units=1, activation = 'sigmoid')) # 添加输出层\n",
    "dnn.summary() # 显示网络模型（这个语句不是必须的）\n",
    "# 编译神经网络，指定优化器，损失函数，以及评估标准\n",
    "dnn.compile(optimizer = 'RMSProp', loss = 'binary_crossentropy', metrics = ['acc'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(5634, 17)"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "X_train.shape"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "X_train = np.asarray(X_train).astype(np.float32)\n",
    "X_test = np.asarray(X_test).astype(np.float32)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/30\n",
      "71/71 [==============================] - 2s 7ms/step - loss: 2.1511 - acc: 0.6872 - val_loss: 3.3458 - val_acc: 0.7657\n",
      "Epoch 2/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 1.7175 - acc: 0.7091 - val_loss: 0.6871 - val_acc: 0.6957\n",
      "Epoch 3/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.7222 - acc: 0.7027 - val_loss: 2.9854 - val_acc: 0.7649\n",
      "Epoch 4/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.7358 - acc: 0.7176 - val_loss: 0.7061 - val_acc: 0.7152\n",
      "Epoch 5/30\n",
      "71/71 [==============================] - 0s 4ms/step - loss: 1.5626 - acc: 0.7224 - val_loss: 1.0453 - val_acc: 0.7791\n",
      "Epoch 6/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.7310 - acc: 0.7182 - val_loss: 6.3833 - val_acc: 0.3966\n",
      "Epoch 7/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.6691 - acc: 0.7238 - val_loss: 0.9222 - val_acc: 0.7968\n",
      "Epoch 8/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.6053 - acc: 0.7253 - val_loss: 3.6203 - val_acc: 0.4419\n",
      "Epoch 9/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.6866 - acc: 0.7211 - val_loss: 2.1239 - val_acc: 0.7595\n",
      "Epoch 10/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.6227 - acc: 0.7275 - val_loss: 0.5856 - val_acc: 0.7258\n",
      "Epoch 11/30\n",
      "71/71 [==============================] - 0s 4ms/step - loss: 1.5233 - acc: 0.7253 - val_loss: 0.6376 - val_acc: 0.7835\n",
      "Epoch 12/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.4671 - acc: 0.7187 - val_loss: 1.2103 - val_acc: 0.7728\n",
      "Epoch 13/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.4340 - acc: 0.7280 - val_loss: 1.8580 - val_acc: 0.7657\n",
      "Epoch 14/30\n",
      "71/71 [==============================] - 0s 4ms/step - loss: 1.5654 - acc: 0.7271 - val_loss: 0.8448 - val_acc: 0.7968\n",
      "Epoch 15/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.3964 - acc: 0.7260 - val_loss: 1.1758 - val_acc: 0.7977\n",
      "Epoch 16/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.3955 - acc: 0.7247 - val_loss: 1.4749 - val_acc: 0.7640\n",
      "Epoch 17/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 1.3664 - acc: 0.7306 - val_loss: 1.0362 - val_acc: 0.7711\n",
      "Epoch 18/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 1.3252 - acc: 0.7291 - val_loss: 2.8873 - val_acc: 0.7622\n",
      "Epoch 19/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.4127 - acc: 0.7286 - val_loss: 2.5095 - val_acc: 0.4623\n",
      "Epoch 20/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.2542 - acc: 0.7340 - val_loss: 2.2466 - val_acc: 0.4667\n",
      "Epoch 21/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.3237 - acc: 0.7286 - val_loss: 1.0671 - val_acc: 0.7959\n",
      "Epoch 22/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.2137 - acc: 0.7435 - val_loss: 1.2360 - val_acc: 0.7773\n",
      "Epoch 23/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 1.2179 - acc: 0.7313 - val_loss: 2.2339 - val_acc: 0.7613\n",
      "Epoch 24/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.2768 - acc: 0.7286 - val_loss: 3.4438 - val_acc: 0.4401\n",
      "Epoch 25/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.2036 - acc: 0.7353 - val_loss: 0.6681 - val_acc: 0.8039\n",
      "Epoch 26/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.1922 - acc: 0.7293 - val_loss: 0.7561 - val_acc: 0.7897\n",
      "Epoch 27/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 1.1306 - acc: 0.7391 - val_loss: 0.4344 - val_acc: 0.7933\n",
      "Epoch 28/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 1.1162 - acc: 0.7286 - val_loss: 1.7996 - val_acc: 0.7640\n",
      "Epoch 29/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.1297 - acc: 0.7324 - val_loss: 0.4825 - val_acc: 0.7311\n",
      "Epoch 30/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 1.0937 - acc: 0.7286 - val_loss: 1.7749 - val_acc: 0.4632\n"
     ]
    }
   ],
   "source": [
    "history = dnn.fit(X_train, y_train, # 指定训练集\n",
    "                  epochs=30,        # 指定训练的轮次\n",
    "                  batch_size=64,    # 指定数据批量\n",
    "                  validation_split=0.2) #这里直接从训练集数据中拆分验证集，更方便"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "def show_history(history): # 显示训练过程中的学习曲线\n",
    "    loss = history.history['loss']\n",
    "    val_loss = history.history['val_loss']\n",
    "    epochs = range(1, len(loss) + 1)\n",
    "    plt.figure(figsize=(12,4))\n",
    "    plt.subplot(1, 2, 1)\n",
    "    plt.plot(epochs, loss, 'bo', label='Training loss')\n",
    "    plt.plot(epochs, val_loss, 'b', label='Validation loss')\n",
    "    plt.title('Training and validation loss')\n",
    "    plt.xlabel('Epochs')\n",
    "    plt.ylabel('Loss')\n",
    "    plt.legend()\n",
    "    acc = history.history['acc']\n",
    "    val_acc = history.history['val_acc']\n",
    "    plt.subplot(1, 2, 2)\n",
    "    plt.plot(epochs, acc, 'bo', label='Training acc')\n",
    "    plt.plot(epochs, val_acc, 'b', label='Validation acc')\n",
    "    plt.title('Training and validation accuracy')\n",
    "    plt.xlabel('Epochs')\n",
    "    plt.ylabel('Accuracy')\n",
    "    plt.legend()\n",
    "    plt.show() "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 864x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "show_history(history) # 调用这个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "45/45 [==============================] - 0s 1ms/step - loss: 1.7446 - acc: 0.4691\n",
      "DNN的测试准确率为 0.47%\n"
     ]
    }
   ],
   "source": [
    "result = dnn.evaluate(X_test, y_test) #评估测试集上的准确率\n",
    "print('DNN的测试准确率为',\"{0:.2f}%\".format(result[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "第一个用户分类结果为: 0\n"
     ]
    }
   ],
   "source": [
    "prediction = dnn.predict(X_test) #预测测试集的图片分类\n",
    "print('第一个用户分类结果为:', np.argmax(prediction[0]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "y_pred = dnn.predict(X_test,batch_size=10) # 预测测试集的标签\n",
    "y_pred_dnn = np.round(y_pred) # 将分类概率值转换成0/1整数值\n",
    "show_matrix(y_test, y_pred_dnn, label='混淆矩阵（神经网络归一化之前）') # 混淆矩阵（神经网络归一化之前）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "              precision    recall  f1-score   support\n",
      "\n",
      "           0       0.88      0.33      0.48      1048\n",
      "           1       0.31      0.86      0.45       361\n",
      "\n",
      "    accuracy                           0.47      1409\n",
      "   macro avg       0.59      0.60      0.47      1409\n",
      "weighted avg       0.73      0.47      0.48      1409\n",
      "\n"
     ]
    }
   ],
   "source": [
    "show_report(X_test, y_test, y_pred_dnn)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 神经网络模型-归一化之后"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.preprocessing import MinMaxScaler #导入归一化缩放器\n",
    "scaler = MinMaxScaler() #创建归一化缩放器\n",
    "X_train = scaler.fit_transform(X_train) #拟合并转换训练集数据\n",
    "X_test = scaler.transform(X_test) #转换测试集数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Epoch 1/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.5632 - acc: 0.7311 - val_loss: 0.5433 - val_acc: 0.7374\n",
      "Epoch 2/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.5233 - acc: 0.7311 - val_loss: 0.4997 - val_acc: 0.7374\n",
      "Epoch 3/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.4858 - acc: 0.7395 - val_loss: 0.4675 - val_acc: 0.7533\n",
      "Epoch 4/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.4622 - acc: 0.7728 - val_loss: 0.4511 - val_acc: 0.7853\n",
      "Epoch 5/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.4501 - acc: 0.7857 - val_loss: 0.4424 - val_acc: 0.7879\n",
      "Epoch 6/30\n",
      "71/71 [==============================] - 0s 3ms/step - loss: 0.4429 - acc: 0.7870 - val_loss: 0.4375 - val_acc: 0.7888\n",
      "Epoch 7/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.4383 - acc: 0.7868 - val_loss: 0.4325 - val_acc: 0.7959\n",
      "Epoch 8/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.4344 - acc: 0.7894 - val_loss: 0.4298 - val_acc: 0.7941\n",
      "Epoch 9/30\n",
      "71/71 [==============================] - 0s 2ms/step - loss: 0.4311 - acc: 0.7901 - val_loss: 0.4260 - val_acc: 0.7950\n",
      "Epoch 10/30\n",
      "35/71 [=============>................] - ETA: 0s - loss: 0.4256 - acc: 0.7929"
     ]
    }
   ],
   "source": [
    "history = dnn.fit(X_train, y_train, # 指定训练集\n",
    "                  epochs=30,        # 指定训练的轮次\n",
    "                  batch_size=64,    # 指定数据批量\n",
    "                  validation_split=0.2) #指定验证集,这里为了简化模型，直接用训练集数据\n",
    "show_history(history) # 调用这个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = dnn.evaluate(X_test, y_test) #评估测试集上的准确率\n",
    "print('DNN（归一化之后）的测试准确率为',\"{0:.2f}%\".format(result[1]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred = dnn.predict(X_test,batch_size=10) # 预测测试集的标签\n",
    "y_pred_dnn_scale = np.round(y_pred) # 将分类概率值转换成0/1整数值\n",
    "show_matrix(y_test, y_pred_dnn_scale, label='混淆矩阵（神经网络归一化之后）') # 混淆矩阵（神经网络归一化之后）"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "show_report(X_test, y_test, y_pred_dnn_scale)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### ROC曲线和AUC"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.metrics import roc_curve\n",
    "from sklearn.metrics import auc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred_logreg = logreg.predict_proba(X_test)[:, 1]\n",
    "fpr_logreg, tpr_logreg, thresholds_logreg = roc_curve(y_test, y_pred_logreg)\n",
    "auc_logreg = auc(fpr_logreg, tpr_logreg)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_pred_dnn_scale = dnn.predict(X_test).ravel()\n",
    "fpr_dnn_scale, tpr_dnn_scale, thresholds_dnn_scale = roc_curve(y_test, y_pred_dnn_scale)\n",
    "auc_dnn_scale = auc(fpr_dnn_scale, tpr_dnn_scale)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.plot([0, 1], [0, 1], 'k--')\n",
    "plt.plot(fpr_logreg, tpr_logreg, label='逻辑回归 (area = {:.3f})'.format(auc_logreg))\n",
    "plt.plot(fpr_dnn_scale, tpr_dnn_scale, label='神经网络 (area = {:.3f})'.format(auc_dnn_scale))\n",
    "plt.xlabel('False Positive Rate')\n",
    "plt.ylabel('True Rositive Rate')\n",
    "plt.title('ROC 曲线')\n",
    "plt.legend(loc='best')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
